Категории
Самые читаемые
RUSBOOK.SU » Научные и научно-популярные книги » Радиотехника » Искусство схемотехники. Том 3 [Изд.4-е] - Пауль Хоровиц

Искусство схемотехники. Том 3 [Изд.4-е] - Пауль Хоровиц

Читать онлайн Искусство схемотехники. Том 3 [Изд.4-е] - Пауль Хоровиц

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 10 11 12 13 14 15 16 17 18 ... 111
Перейти на страницу:

Программа сбрасывает выходной сигнал КОНЕЦ, считывает состояние управляющей панели и использует соответствующим образом полученные значения (устанавливая программные флаги типа auto__loop и параметры вроде dwell__per__bin и num__sweeps). Обратите внимание на использование таблицы decode__tbl (и косвенной адресации с индексацией) для получения значений, соответствующих положениям переключателей.

Далее программа очищает массивы DATA и NORM, инициализирует некоторые регистры (адресов и данных) и сбрасывает флаг останова. Последний шаг заключается в изменении содержимого вектора INT5 (который пока указывает на метку idle__int в обработчике прерываний) на адрес wait__trig или sweep__start в зависимости от того, какой режим установлен на управляющей панели: внешнего запуска или автозапуска.

Наконец, главная программа входит в «рабочий» цикл, в котором многократно выполняются два действия: вызов подпрограммы update (обновления массива DISPLAY в соответствии с содержимым массива DATA) и проверка флага останова stop__flag. На фоне этого унылого цикла прерывания тайком выполняют все то, ради чего был сделан наш прибор.

Главная программа: подпрограммы. Перед тем как взяться за наиболее сложную программу нашего комплекса - обработчик прерываний, рассмотрим две подпрограммы, вызываемые главной программой (рис. 11.20).

Рис. 11.20. Структурные схемы подпрограмм.

Подпрограмма clear__arrays заполняет нулями оба массива DATA и NORM; массив DISPLAY очищать нет необходимости, потому что программа update сразу же скопирует нули из DATA в DISPLAY. Эта программа обновляет за раз одно значение из массива DISPLAY, используя для этого текущие параметры изображения с управляющей панели и входные данные из массивов DATA и NORM; она также обновляет состояние порта ЭЛД, копируя байт памяти led__store.

Рассмотрим сначала простую подпрограмму clear__arrays из программы 11.3. Регистры А0 и А1 используются, как указатели двух массивов, и все 32 разряда D0 заполняются нулями. Счетчик D1 инициализируется величиной, равной размеру массива минус один; сейчас станет понятно, зачем это нужно. В цикле слово или длинное слово нулей пересылается в массивы с помощью косвенной адресации (с постинкрементом); вспомните, что постинкрементная адресация — штука интеллигентная, она инкрементирует адресный регистр правильным образом, прибавляя в нашем случае 2 в операции со словом и 4 в операции с длинным словом. Команда DBF заслуживает особого объяснения. Она представляет собой один из вариантов команды DBcc, для которого код условия ее = «ложь» (False). Любая команда (в общем виде) DBcc Dn, метка фактически проверяет два условия.

Сначала она анализирует выполнение условия ее (т. е. состояние флагов, установленное предыдущей командой), при этом, если ее = «истина», ничего не делается (т. е. команда как бы пропускается и ЦП переходит к выполнению следующей команды). Если, однако, ее = «ложь», происходит декремент указанного регистра (как слова) и переход на метку метка, с предварительным анализом содержимого регистра. Если в регистре обнаруживается — 1, переход на метку не осуществляется, и выполняется следующая команда. В нашем случае команда DBcc действует просто как оператор цикла, так как ее = F («всегда ложь», см. табл. 11.1), поэтому декремент D1 осуществляется безусловно, до тех пор, пока не обнаружится D1 = — 1. Несмотря на эти сложности (а также и необходимость использовать счетчик длиной в слово), команда DBcc весьма удобна, так как заменяет две команды (SUBQ, Вcс), и выполняется очень быстро. Поскольку она проверяет счетчик на —1, последний следует инициализировать числом, на 1 меньшим требуемого числа шагов, чем и объясняется инициализация, использованная в программе. Подпрограмма заканчивается обычной командой RTS (возврат из подпрограммы), восстанавливающей исходное содержимое PC (программного счетчика) и осуществляющей таким образом возврат в вызывающую программу.

Заметьте, что в начале подпрограммы не понадобилось сохранять содержимое каких-либо регистров, потому что вызывающая программа не оставила ничего ценного в регистрах D0-D1 и А0-А1. Обратите также внимание на использование MOVE, а не CLR для обнуления массивов; оказывается, команда MOVE работает быстрее CLR из-за особенностей архитектуры МП 68000 — при выполнении CLR МП 68000 сначала инициализирует цикл чтения, а затем — цикл записи. Разработчики приняли такое, на первый взгляд, странное решение для упрощения логики ЦП.

Упражнение 11.13. Напишите вариант подпрограммы clear arrays с использованием команд SUBQ и Всс вместо DBF. Напишите еще один вариант, в котором вместо MOVE используется CLR.

Подпрограмма update более содержательна. Ее задача — обновлять массив DISPLAY в памяти (а также и состояние ЭЛД); она многократно вызывается в обоих циклах главной программы. Поскольку прерывания имеют приоритет, они выполняют свою работу в точном соответствии с расписанием (каждые 100 мкc), все же оставшееся время отдается подпрограмме update. Ее действия начинаются с пересылки образа ЭЛД в памяти в физический порт ЭЛД. Даже эта относительно простая операция требует некоторых пояснений. Естественный вопрос, который должен прийти вам в голову, — это почему бы, желая установить или сбросить бит ЭЛД, не обновлять ЭЛД непосредственно? В ответ надо указать на два обстоятельства. Во-первых, просто записать новый байт в порт ЭЛД нельзя, так как при этом потеряются значения остальных битов; либо мы должны иметь порт ЭЛД с возможностью как записи, так и чтения, либо надо хранить в памяти образ ЭЛД. Поскольку из нашего порта ЭЛД читать нельзя, в памяти предусмотрена ячейка led__store, хранящая копию последнего байта, посланного в порт ЭЛД. Во-вторых, раз уж такая ячейка все равно есть, мы можем сэкономить время в критических циклах обработчика прерываний, обновляя в них только ячейку led__store. Передачу же сообщения на ЭЛД-индикатор передней панели будет осуществлять подпрограмма update в ходе своего выполнения. Все это станет более понятным, когда мы приступим к рассмотрению обработчика прерываний.

Упражнение 11.14. Какие дополнительные (очень несложные) аппаратные средства требуются для того, чтобы можно было читать из порта ЭЛД? Проявите сообразительность, чтобы дополнительная дешифрация адреса получилась простой.

Оставшаяся часть подпрограммы update обновляет массив DISPLAY. Прежде всего из памяти извлекается смещение (число элементов от начала массива) очередного обновляемого элемента. (Для этого было бы неплохо использовать выделенный адресный регистр, но при распределении регистров приоритет был, конечно, отдан обработчику прерываний.) Смещение умножается на 4 (сдвигом влево на 2 бит), чтобы его можно было использовать для индексной адресации в массиве DATA длинных чисел. Переслав в D1 очередной элемент из DATA, мы считываем с управляющей панели текущее значение масштаба изображения и маскируем его, чтобы получить число от 0 до 15. Число 15 ($0F) обозначает автомасштабирование, в то время как меньшие числа определяют фиксированный масштаб в виде степени 2. Мы либо соответствующим образом сдвигаем значение элемента, либо переходим на программный блок автомасштабирования.

Для выполнения автомасштабирования нам надо значение текущего (индексированного с помощью update__offset) элемента DATA разделить на текущее значение из массива NORM (которое говорит, сколько разверток включено в значение DATA), а затем еще раз разделить на ширину канала (которая говорит, сколько выборок было сделано в каждой развертке). Перед любым делением всегда проверяйте на нуль! Наконец, как при сдвиге, так и при автомасштабировании мы должны преобразовать полученное длинное данное со знаком в байт со знаком. В случае автомасштабирования результирующее длинное число всегда находится в диапазоне ±128. В случае фиксированного масштаба, если выбрать масштаб меньше отсчета в наиболее заполненном канале, произойдет переполнение. Лучше всего сделать так, чтобы при переполнении точки, выходящие за верхний край изображения, «прокручивались» в его низ и наоборот. Написав несколько чисел и проиграв с ними разные варианты, вы легко убедитесь, что правильный алгоритм заключается в усечении числа до 8 бит и инвертировании затем старшего бита. Мы реализовали этот алгоритм с помощью команды изменения бита BCNG, после которой выполняется байтовая пересылка (командой MOVE) в массив DISPLAY. Далее мы инкрементируем и сохраняем индекс update__offset и, наконец, выполняем команду RTS.

Обработчик прерываний. Наконец мы добрались до обработчика прерываний — центральной фигуры всей программы. Перед нами четыре точки входа в обработчик, инициируемый прерываниями от таймера; перед нами также простенький обработчик bad__int ложных прерываний, а также и всех остальных векторизованных ошибок и ловушек (табл. 11.5). Займемся ради разминки программой bad__int, а когда не останется отговорок, примемся за обработчик прерываний от таймера.

1 ... 10 11 12 13 14 15 16 17 18 ... 111
Перейти на страницу:
На этой странице вы можете бесплатно скачать Искусство схемотехники. Том 3 [Изд.4-е] - Пауль Хоровиц торрент бесплатно.
Комментарии
Открыть боковую панель
Комментарии
Сергій
Сергій 25.01.2024 - 17:17
"Убийство миссис Спэнлоу" от Агаты Кристи – это великолепный детектив, который завораживает с первой страницы и держит в напряжении до последнего момента. Кристи, как всегда, мастерски строит